package org.springblade.message.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.core.secure.BladeUser;
import org.springblade.core.secure.utils.SecureUtil;
import org.springblade.core.tool.constant.BladeConstant;
import org.springblade.core.tool.utils.BeanUtil;
import org.springblade.message.entity.Message;
import org.springblade.message.entity.MessageLog;
import org.springblade.message.enums.MessageEnum;
import org.springblade.message.mapper.MessageLogMapper;
import org.springblade.message.mapper.MessageMapper;
import org.springblade.message.params.MessageParams;
import org.springblade.message.sender.IMqSender;
import org.springblade.message.service.IMessageService;
import org.springblade.message.vo.MqMessageVO;
import org.springblade.message.vo.TopMessageVO;
import org.springblade.system.cache.SysCache;
import org.springblade.system.user.cache.UserCache;
import org.springblade.system.user.feign.IUserClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 消息服务实现类
 *
 * @author weikun
 * @since 2021-05-08
 */
@Service
@Slf4j
public class MessageServiceImpl extends BaseServiceImpl<MessageMapper, Message> implements IMessageService {
	@Autowired
	private MessageLogMapper messageLogMapper;
	@Autowired
	private IUserClient iUserClient;
	@Autowired
	private IMqSender mqSender;


	@Override
	public TopMessageVO selectTopMessage() {
		TopMessageVO result = new TopMessageVO();
		//查询前十条消息
		List<Message> topMessageList = baseMapper.selectTopMessageList(SecureUtil.getUserId());
		for (Message message : topMessageList) {
			message.setCreateUserName(UserCache.getUser(message.getCreateUser()).getName());
		}
		//查询未读消息数量
		LambdaQueryWrapper<Message> queryWrapper = new LambdaQueryWrapper<Message>().eq(Message::getReceiveUser, SecureUtil.getUserId())
			.eq(Message::getIsDeleted, BladeConstant.DB_NOT_DELETED)
			.eq(Message::getIsRead, MessageEnum.UNREAD.getCode());

		result.setMessageList(topMessageList);
		result.setUnReadCount(Math.toIntExact(baseMapper.selectCount(queryWrapper)));
		return result;
	}

	@Override
	public MessageLog getSendDetail(Long id) {
		MessageLog messageLog = messageLogMapper.selectById(id);
		messageLogHandle(messageLog);
		return messageLog;
	}


	@Override
	public IPage<Message> selectMessagePage(IPage<Message> page, Message message) {
		List<Message> messageList = baseMapper.selectMessagePage(page, message);
		for (Message msg : messageList) {
			msg.setCreateUserName(UserCache.getUser(msg.getCreateUser()).getName());
		}
		return page.setRecords(messageList);
	}

	@Override
	public IPage<MessageLog> selectMessageSendPage(IPage<MessageLog> page, MessageLog message) {
		List<MessageLog> messageSendList = messageLogMapper.selectMessageLogPage(page, message);
		for (MessageLog messageLog : messageSendList) {
			messageLogHandle(messageLog);
		}
		return page.setRecords(messageSendList);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean sendMessage(MessageParams messageParams) {
		BladeUser user = SecureUtil.getUser();
		MessageLog messageLog = new MessageLog(messageParams);
		if (user != null){
			messageLog.setCreateUser(user.getUserId());
		}else {
			//将消息发送者设置为管理员
			/*messageLog.setCreateUser(userService.getOne(new QueryWrapper<User>().lambda()
				.eq(User::getAccount,"admin")
				.last("limit 1"))
				.getId());*/
			messageLog.setCreateUser(iUserClient.userByAccount("000000", "admin")
				.getData().getId());
		}
		messageLog.setIsDeleted(BladeConstant.DB_NOT_DELETED);
		//保存发送记录
		messageLogMapper.insert(messageLog);
		//消息详情保存
		Message message = new Message(messageLog);
		//mq消息封装
		MqMessageVO mqMessageVO=new MqMessageVO(messageLog);
		if (MessageEnum.GROUP.getCode() == messageParams.getType()//如果是群体发送
			||MessageEnum.TREE_GROUP.getCode() == messageParams.getType()
			||MessageEnum.MULTIPLE.getCode() == messageParams.getType()) {
			//需要保存的消息
			List<Message> messageList = new ArrayList<>();
			//查询部门下用户，可改feign调用user-api，若频繁调用可加缓存
			Set<Long> userSet = new HashSet<>();
			if (MessageEnum.GROUP.getCode() == messageParams.getType()//如果是群体发送
				||MessageEnum.TREE_GROUP.getCode() == messageParams.getType()) {
				//获取部门id
				List<Long> receiveGroupList = messageParams.getReceiveGroupList();
				List<Long> deptList = new ArrayList<>();
				//如果是群发并下发到下级部门  则修改下发部门id
				if (MessageEnum.TREE_GROUP.getCode() == messageParams.getType()) {
					for (Long group : receiveGroupList) {
						List<Long> idsByDept = messageLogMapper.selectDeptTreeIdsByDept(group);
						deptList.addAll(idsByDept);
					}
				} else {
					deptList.addAll(receiveGroupList);
				}
				for (Long deptId : deptList) {
					List<Long> userIdList = messageLogMapper.selectUserIdsByDept(deptId);
					userSet.addAll(userIdList);
				}
			}else {
				List<Long> receiveIdList = messageParams.getReceiveIdList();
				userSet = new HashSet<>(receiveIdList);
			}
			for (Long userId : userSet) {
				log.info("下发到了用户{}",userId);
				Message newMessage = new Message();
				BeanUtil.copy(message,newMessage);
				newMessage.setReceiveUser(userId);
				newMessage.setId(null);
				messageList.add(newMessage);
			}
			this.saveBatch(messageList);
			mqSender.sendGroupMsg(null,userSet, mqMessageVO);
		} else {
			this.save(message);
			mqSender.sendSingleMsg(messageParams.getReceiveUser(), mqMessageVO);
		}

		return true;
	}


	/**
	 * 发送消息记录接收人、部门处理
	 *
	 * @param messageLog 发送消息记录
	 */
	private void messageLogHandle(MessageLog messageLog) {
		if (messageLog.getType().equals(MessageEnum.SINGLE.getCode())) {
			String name = UserCache.getUser(messageLog.getReceiveUser()).getName();
			if (name != null){
				messageLog.setReceiveUserName(name);
			}else {
				messageLog.setReceiveUserName("未知");
			}
		}
		if (messageLog.getType().equals(MessageEnum.GROUP.getCode())
			|| messageLog.getType().equals(MessageEnum.TREE_GROUP.getCode())) {
			List<String> deptName = new ArrayList<>();
			for (String groupId : messageLog.getReceiveGroup().split(",")) {
				deptName.add(SysCache.getDeptName(Long.valueOf(groupId)));
			}
			messageLog.setReceiveGroupName(deptName);
		}
	}


}
